//给定一个未排序的整数数组 nums ，找出数字连续的最长序列（不要求序列元素在原数组中连续）的长度。 
//
// 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 
//
// 
//
// 示例 1： 
//
// 
//输入：nums = [100,4,200,1,3,2]
//输出：4
//解释：最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。 
//
// 示例 2： 
//
// 
//输入：nums = [0,3,7,2,5,8,4,6,0,1]
//输出：9
// 
//
// 
//
// 提示： 
//
// 
// 0 <= nums.length <= 105 
// -109 <= nums[i] <= 109 
// 
// Related Topics 并查集 数组 哈希表 
// 👍 965 👎 0

package com.cute.leetcode.editor.cn;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class LongestConsecutiveSequence {
    public static void main(String[] args) {
        int[] nums = {1,2,3,4,5,7,8,9,10,11,12,13,14,15,16};
        new LongestConsecutiveSequence().new Solution().longestConsecutive2(nums);
    }
    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        /**
         * 两种方法思路上是一样的，只是实现起来有一些差别罢了
         *
         * 1.直接迭代：思路比较直接，没有使用hash进行匹配，直接对数组进行的迭代
         *  先将数组进行排序，然后迭代时判断当前值与下一个值是否差1，差1的话max++，如果相等就跳过，否则max置初始值1
         *
         * 2.题解中的方法，使用hashset：
         *  其实借助set的话，在添加元素后会去除重复元素且进行排序
         *  遍历set集合，判断当前key的前一个key是否存在，存在的话说明当前key不会是连续数组的起始位置
         *  如果前一个key不存在的话，就从当前key开始进行向后迭代，直到不存在下一个连续的key为止
         *  逻辑上会遍历set中的所有元素，但是debug的时候为什么会跳过很多循环呢？
         */
        public int longestConsecutive(int[] nums) {
            if (nums.length == 0) return 0;
            Arrays.sort(nums);
            int res = 1;
            int max = 1;
            for (int i = 0; i < nums.length-1; i++) {
                if (nums[i+1] - nums[i]==1) max++;
                else if (nums[i+1] != nums[i]) {
                    max = 1;
                }
                res = Math.max(res, max);
            }
            return res;
        }


        public int longestConsecutive2(int[] nums) {
            if (nums.length == 0) return 0;
            int res = 1;
            Set<Integer> set = new HashSet<>();
            for (int num : nums)set.add(num);
            for (int x : set){
                if (!set.contains(x - 1)){
                    int y = x;
                    while (set.contains(y + 1)) y++;
                    res = Math.max(res, y - x + 1 );
                }
            }
            return res;
        }
    }
//leetcode submit region end(Prohibit modification and deletion)

}